package example.demo.route.handler.impl;

import example.demo.route.handler.SqlHandlerParent;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.jdbc.ConnectionLogger;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.Invocation;
import org.springframework.core.annotation.Order;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

@Component
@Order(-100)
public class SelectSqlHandler extends SqlHandlerParent {
    //SELECT id,username,real_name,sex,mobile,email,note,position_id FROM t_user WHERE id=?
    @Override
    public String getTableName(String sql) {
        //获取的table-name已经没有了前后空格
        return sql.substring(sql.lastIndexOf("FROM") + 5, sql.lastIndexOf("WHERE") - 1);
    }


//    public static void main(String[] args) {//wwt_userww 说明前后两个空格
//        SelectSqlHandler selectSqlHandler = new SelectSqlHandler();
//        System.out.println(selectSqlHandler.getTableName("SELECT id,username,real_name,sex,mobile,email,note,position_id FROM t_user WHERE id=?").
//                replaceAll(" ", "ww"));
//    }

    @Override
    public boolean isSupport(String sql) {
        return sql.contains("SELECT") || sql.contains("select");
    }

    @Override
    public Object handler(Integer[] integers, String sql, Invocation invocation, BoundSql boundSql, Field sqlField, StatementHandler statementHandler) throws Exception {
        for (Integer integer : integers) {
            int i = integer.intValue();
            if (0 != i) {
                String tableName = getTableName(sql);
                String newTableName = tableName + i /*+ " "*/;
                String newSql = sql.replace(tableName, newTableName);
                /*替换sql*/
                sqlField.set(boundSql, newSql);
                /*拿到数据库连接*/
                //A下--------->
                Connection connection = DataSourceUtils.getConnection(dataSource);
                /*打印日志，如果不要打印日志的话，只要替换sql就ok，就可以直接调用invocation.proceed()*/
                Connection connectionProxy = ConnectionLogger.newInstance(connection, getStatementLog(statementHandler), 1);
                Statement statement = statementHandler.prepare(connectionProxy, null);
                statementHandler.parameterize(statement);
                invocation.getArgs()[0] = statement;
                //B上--------->
                //A下与B上代码注释掉都可以。只不过是不打印替换后的sql日志而已
                List<Object> list = (List<Object>) invocation.proceed();
                if (list.size() > 0) {
                    return list;
                }
            } else {
                //0就无需替换table-name了
                List<Object> list = (List<Object>) invocation.proceed();
                if (list.size() > 0) {
                    return list;
                }
            }
        }
        /*没查到，返回一个空的list，省的后面包空指针异常*/
        return new ArrayList<>();
    }

}
